package com.itcs.app.pay.nowpay.callback;

import java.io.BufferedReader;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;
import com.itcs.app.pay.constants.CallbackPayStatus;
import com.itcs.app.pay.model.QrcodeCallBackData;
import com.itcs.app.pay.model.TradePayCallBackData;
import com.itcs.app.pay.nowpay.NowPayPlatform;
import com.itcs.app.pay.nowpay.constants.PayChannelType;
import com.itcs.app.pay.nowpay.properties.BsConfig;
import com.itcs.app.pay.nowpay.properties.ZsConfig;
import com.itcs.app.pay.service.PayService;
import com.itcs.app.service.TransJournalService;
import com.itcs.app.util.FormDateReportConvertor;
import com.itcs.app.util.MD5Facade;
import com.itcs.app.util.ParamMap;
import com.itcs.app.util.PayType;
import com.itcs.box.util.LogUtils;
import com.itcs.trading.model.TransJournal;

/**
 * 现在支付回调API
 */
@Controller
@RequestMapping("/callBack")
public class CallBackApi {

	private Log logger = LogFactory.getLog(getClass());

	@Autowired
	private ZsConfig zsConfig;
	@Autowired
	private BsConfig bsConfig;
	@Autowired
	private PayService payService;
	@Autowired
	private TransJournalService transJournalService;

	/**
	 * 现在支付,主扫回调 商户后台通知URL
	 * 
	 * @param request
	 * @param response
	 * @throws IOException
	 */
	@ResponseBody
	@RequestMapping(value = "achBackNotify")
	public void achBackNotify(HttpServletRequest request, HttpServletResponse response) throws IOException {
		try {
			// 获取通知数据需要从body中流式读取
			BufferedReader reader = request.getReader();
			StringBuilder reportBuilder = new StringBuilder();
			String tempStr = "";
			while ((tempStr = reader.readLine()) != null) {
				reportBuilder.append(tempStr);
			}
			String reportContent = reportBuilder.toString();
			Map<String, String> dataMap = FormDateReportConvertor.parseFormDataPatternReportWithDecode(reportContent, "UTF-8", "UTF-8");
			// dataMap 用于url方式传进来的
			if (dataMap == null || dataMap.size() < 2) {
				dataMap = new HashMap<String, String>();
				ParamMap param = ParamMap.init(request);
				String mhtOrderNo = param.getString("mhtOrderNo");// 自动订单号
				String nowPayOrderNo = param.getString("nowPayOrderNo");// 现在支付流水号
				String payChannelType = param.getString("payChannelType");// 用户所选渠道类型：12 支付宝 13 微信
				String mhtOrderAmt = param.getString("mhtOrderAmt");// 订单交易金额
				String channelOrderNo = param.getString("channelOrderNo");// 渠道订单号,微信或支付宝订单号,支付成功时返回
				String deviceType = param.getString("deviceType");// 0600公众号
				dataMap.put("mhtOrderNo", mhtOrderNo);
				dataMap.put("nowPayOrderNo", nowPayOrderNo);
				dataMap.put("payChannelType", payChannelType);
				dataMap.put("mhtOrderAmt", mhtOrderAmt);
				dataMap.put("channelOrderNo", channelOrderNo);
				dataMap.put("deviceType", deviceType);

			}
			logger.info(LogUtils.build("achBackNotify", "现在支付回调", "订单号:" + dataMap.get("mhtOrderNo"), JSON.toJSONString(dataMap)));

			// ================================================现在支付验证-start===========================================
			// 去除签名值
			String signature = dataMap.remove("signature");
			
			String deviceType = dataMap.get("deviceType");
			if ("05".equals(deviceType)) {
				// 被扫回调
				logger.info(LogUtils.build("achBackNotify", "现在支付被扫回调", "订单号:" + dataMap.get("mhtOrderNo")));
				// 验证签名
				boolean isValidSignature = MD5Facade.validateFormDataParamMD5(dataMap, bsConfig.getAppKey(), signature);
				if (!isValidSignature) {
					response.getOutputStream().write("success=N".getBytes());
					logger.error(LogUtils.build("achBackNotify", "现在支付被扫回调", "签名验证失败", JSON.toJSONString(dataMap)));
					return;
				}
				// 商户订单号
				String transNo = dataMap.get("mhtOrderNo");
				// 交易状态
				String transStatus = dataMap.get("transStatus");
				String payStatus = CallbackPayStatus.PAY_FAILED;
				if ("A001".equals(transStatus)) {
					payStatus = CallbackPayStatus.PAY_SUCCESS;
				}
				// 支付渠道
				String payChannelType = dataMap.get("payChannelType");
				// 转换渠道代码
				String payChannelCode = PayChannelType.payChannelType2Code(payChannelType);
				// 第三方支付平台订单号
				String platformOrderNo = dataMap.get("nowPayOrderNo");
				// 支付渠道订单号
				String channelOrderNo = dataMap.get("channelOrderNo");

				TradePayCallBackData tradePayCallBackData = new TradePayCallBackData(transNo, payStatus, platformOrderNo, channelOrderNo,
						NowPayPlatform.TYPE, payChannelCode);
				payService.tradePayCallback(tradePayCallBackData);
			} else {
				// 公众号主扫回调
				logger.info(LogUtils.build("achBackNotify", "现在支付公众号主扫回调", "订单号:" + dataMap.get("mhtOrderNo")));
				// 验证签名
				
				boolean isValidSignature = MD5Facade.validateFormDataParamMD5(dataMap, zsConfig.getAppKey(), signature);
				if (!isValidSignature) {
					response.getOutputStream().write("success=N".getBytes());
					logger.error(LogUtils.build("achBackNotify", "现在支付公众号主扫回调", "签名验证失败", JSON.toJSONString(dataMap)));
					return;
				}
				// 商户订单号
				String transNo = dataMap.get("mhtOrderNo");

				String payStatus = CallbackPayStatus.PAY_FAILED;
				if ("A001".equals(dataMap.get("transStatus"))) {
					payStatus = CallbackPayStatus.PAY_SUCCESS;
				}

				// 支付渠道
				String payChannelType = dataMap.get("payChannelType");
				// 转换渠道代码
				String payChannelCode = PayChannelType.payChannelType2Code(payChannelType);
				// 第三方支付平台订单号
				String platformOrderNo = dataMap.get("nowPayOrderNo");
				// 支付渠道订单号
				String channelOrderNo = dataMap.get("channelOrderNo");

				QrcodeCallBackData qrcodeCallBackData = new QrcodeCallBackData(transNo, payStatus, platformOrderNo, channelOrderNo,
						NowPayPlatform.TYPE, payChannelCode);
				payService.qrcodeCallback(qrcodeCallBackData);
			}
			response.getOutputStream().write("success=Y".getBytes());
		} catch (Exception ex) {
			logger.error(LogUtils.build("achBackNotify", "现在支付被扫回调", "回调处理失败," + ex.getMessage()), ex);
			response.getOutputStream().write("success=N".getBytes());
		}
	}

	/**
	 * 商户前台通知URL
	 * 
	 * @param request
	 * @param response
	 * @throws IOException
	 */
	@ResponseBody
	@RequestMapping(value = "achFrontNotify")
	public ModelAndView achFrontNotify(HttpServletRequest request, HttpServletResponse response) throws IOException {
		try {
			// 获取通知数据需要从body中流式读取
			BufferedReader reader = request.getReader();
			StringBuilder reportBuilder = new StringBuilder();
			String tempStr = "";
			while ((tempStr = reader.readLine()) != null) {
				reportBuilder.append(tempStr);
			}
			String reportContent = reportBuilder.toString();
			Map<String, String> dataMap = FormDateReportConvertor.parseFormDataPatternReportWithDecode(reportContent, "UTF-8", "UTF-8");
			if (dataMap == null || dataMap.size() < 2) {
				dataMap = new HashMap<String, String>();
				ParamMap param = ParamMap.init(request);
				String mhtOrderNo = param.getString("mhtOrderNo");// 自动订单号
				String nowPayOrderNo = param.getString("nowPayOrderNo");// 现在支付订单号
				String payChannelType = param.getString("payChannelType");// 用户所选渠道类型：12 支付宝 13 微信
				String mhtOrderAmt = param.getString("mhtOrderAmt");// 订单交易金额
				dataMap.put("mhtOrderNo", mhtOrderNo);
				dataMap.put("nowPayOrderNo", nowPayOrderNo);
				dataMap.put("payChannelType", payChannelType);
				dataMap.put("mhtOrderAmt", mhtOrderAmt);

			}
			logger.info(LogUtils.build("achFrontNotify", "公众号主扫页面回调", "订单号:" + dataMap.get("mhtOrderNo"), JSON.toJSONString(dataMap)));
			logger.info("公众号主扫页面回调数据:[" + dataMap.toString() + "]");
			
			
			Boolean isOK = false;
			if ("A001".equals(request.getParameter("transStatus"))) {
				TransJournal transJournal = transJournalService.selectByTransNo(request.getParameter("mhtOrderNo"));
				String mhtOrderAmt = String.valueOf(transJournal.getTollFare());
				int payerId = transJournal.getPayerId();
				request.setAttribute("mhtOrderAmt", mhtOrderAmt);
				request.setAttribute("mhtOrderNo", request.getParameter("mhtOrderNo"));
				
				if (payerId == PayType.主扫支付宝 || payerId == PayType.被扫支付宝) {
					request.setAttribute("payChannelType", "支付宝");
				} else if (payerId == PayType.主扫微信 || payerId == PayType.被扫微信) {
					request.setAttribute("payChannelType", "微信");
				}
				request.setAttribute("carPlate", transJournal.getCarPlate());
				BigDecimal tollFareAmount = transJournal.getTollFare();// 通行费应付金额
				request.setAttribute("mhtOrderAmt", tollFareAmount.divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP).doubleValue());// 页面单位是元所以除100
				isOK = true;
			}
			logger.info(LogUtils.build("achFrontNotify", "公众号主扫页面回调", "订单号:" + dataMap.get("mhtOrderNo") + ",处理结果:" + isOK));
			if (isOK) {
				return new ModelAndView("/wap4");
			}
		} catch (Exception ex) {
			logger.error(LogUtils.build("achFrontNotify", "公众号主扫页面回调", "回调处理失败," + ex.getMessage()), ex);
		}
		return new ModelAndView("/wap5");
	}
/*	@ResponseBody
	@RequestMapping(value = "achFrontNotify")
	public ModelAndView achFrontNotify(HttpServletRequest request, HttpServletResponse response) throws IOException {
		try {
			// 获取通知数据需要从body中流式读取
			BufferedReader reader = request.getReader();
			StringBuilder reportBuilder = new StringBuilder();
			String tempStr = "";
			while ((tempStr = reader.readLine()) != null) {
				reportBuilder.append(tempStr);
			}
			String reportContent = reportBuilder.toString();
			Map<String, String> dataMap = FormDateReportConvertor.parseFormDataPatternReportWithDecode(reportContent, "UTF-8", "UTF-8");
			if (dataMap == null || dataMap.size() < 2) {
				dataMap = new HashMap<String, String>();
				ParamMap param = ParamMap.init(request);
				String mhtOrderNo = param.getString("mhtOrderNo");// 自动订单号
				String nowPayOrderNo = param.getString("nowPayOrderNo");// 现在支付订单号
				String payChannelType = param.getString("payChannelType");// 用户所选渠道类型：12 支付宝 13 微信
				String mhtOrderAmt = param.getString("mhtOrderAmt");// 订单交易金额
				dataMap.put("mhtOrderNo", mhtOrderNo);
				dataMap.put("nowPayOrderNo", nowPayOrderNo);
				dataMap.put("payChannelType", payChannelType);
				dataMap.put("mhtOrderAmt", mhtOrderAmt);
				
			}
			logger.info(LogUtils.build("achFrontNotify", "公众号主扫页面回调", "订单号:" + dataMap.get("mhtOrderNo"), JSON.toJSONString(dataMap)));
			logger.info("公众号主扫页面回调数据:[" + dataMap.toString() + "]");
			Boolean isOK = false;
			if ("A001".equals(dataMap.get("transStatus"))) {
				String mhtOrderAmt = dataMap.get("mhtOrderAmt");
				if (mhtOrderAmt != null && !mhtOrderAmt.trim().equals("")) {
					request.setAttribute("mhtOrderAmt", mhtOrderAmt);
					request.setAttribute("mhtOrderNo", dataMap.get("mhtOrderNo"));
					isOK = true;
					if (PayChannelType.ALIPAY.equals(dataMap.get("payChannelType"))) {
						request.setAttribute("payChannelType", "支付宝");
					} else if (PayChannelType.WECHAT_PAY.equals(dataMap.get("payChannelType"))) {
						request.setAttribute("payChannelType", "微信");
					}
					TransJournal transJournal = transJournalService.selectByTransNo(dataMap.get("mhtOrderNo"));
					if (transJournal == null) {// 查不到数据，返回相关信息
						request.setAttribute("carPlate", "未知");
					} else {
						request.setAttribute("carPlate", transJournal.getCarPlate());
						BigDecimal tollFareAmount = transJournal.getTollFare();// 通行费应付金额
						request.setAttribute("mhtOrderAmt", tollFareAmount.divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP).doubleValue());// 页面单位是元所以除100
						
					}
				}
			}
			logger.info(LogUtils.build("achFrontNotify", "公众号主扫页面回调", "订单号:" + dataMap.get("mhtOrderNo") + ",处理结果:" + isOK));
			if (isOK) {
				return new ModelAndView("/wap4");
			}
		} catch (Exception ex) {
			logger.error(LogUtils.build("achFrontNotify", "公众号主扫页面回调", "回调处理失败," + ex.getMessage()), ex);
		}
		return new ModelAndView("/wap5");
	}*/
}
